// message.h
// Created by yan on 2020/6/17.
// 消息模块。我自己写的一套消息机制，虽然 windows.h 已经有一套现成的消息机制，但我还是尝试自己造一个。

#ifndef C_PROJECT_MESSAGE_H
#define C_PROJECT_MESSAGE_H


#include "my_queue.h"
#include "utils.h"
#include <pthread.h>
#include <windows.h>

// 下面定义了一些消息。
#define EVENT_MY_KEY            1      // 按键消息。
#define EVENT_MY_EXIT           0      // 程序退出消息。
#define EVENT_MY_MUSIC_DONE     2      // 音乐播放完成消息。
#define EVENT_MY_MUSIC_START    3      // 音乐播放开始消息。
#define EVENT_MY_PLAYER_START   4      // 本程序启动消息。
#define EVENT_MY_LIST_END       5      // 到达音乐列表末尾消息。
#define EVENT_MY_LIST_BEGIN     6      // 到达音乐列表开头消息。

// 下面定义了一些按键，右边的数字的键码。
#define KEY_MY_ESC              27
#define KEY_MY_CTRL_C           3
#define KEY_MY_UP               72
#define KEY_MY_RIGHT            77
#define KEY_MY_LEFT             75
#define KEY_MY_DOWN             80
#define KEY_MY_ENTER            13
#define KEY_MY_APACE            32
#define KEY_MY_PAGE_UP          73
#define KEY_MY_PAGE_DOWN        81
#define KEY_MY_S                115
#define KEY_MY_F5               63
#define KEY_MY_W                119
#define KEY_MY_DEL              83
#define KEY_MY_ARROW            224
#define KEY_MY_FUNCTION         0


// 声明消息队列和线程锁。
static Queue_MSG_MY MyMsgQueue;
static pthread_mutex_t lock;

// 消息队列初始化。
void msgQueue_My_init() {
    Queue_MSG_MY_init(&MyMsgQueue);
    pthread_mutex_init(&lock, NULL);
}

// 清空消息队列。
void msgQueue_My_clear() {
    Queue_MSG_MY_destroy(&MyMsgQueue);
}

// 销毁消息队列，释放内存。
void msgQueue_My_destroy() {
    msgQueue_My_clear();
    pthread_mutex_destroy(&lock);
}

// 获取消息，这是阻塞函数，没有获取到消息会一直停在这里，直到获取到消息。
void getMessage_My(MSG_MY *pMsg) {
    while (true) {
        while (Queue_MSG_MY_empty(&MyMsgQueue)) Sleep(10);
        pthread_mutex_lock(&lock);
        if (not Queue_MSG_MY_empty(&MyMsgQueue)) {
            Queue_MSG_MY_pop(&MyMsgQueue, pMsg);
            pthread_mutex_unlock(&lock);
            return;
        }
        pthread_mutex_unlock(&lock);
    }
}

// 发送消息到消息队列。
void postMessage_My(const MSG_MY *pMsg) {
    pthread_mutex_lock(&lock);
    Queue_MSG_MY_push(&MyMsgQueue, pMsg);
    pthread_mutex_unlock(&lock);
}

#endif //C_PROJECT_MESSAGE_H
